"""
财务科目分类映射模块
基于PRD精简版中定义的资产负债表科目分类体系
"""

import pandas as pd
from typing import Dict, List, Any
import logging

logger = logging.getLogger(__name__)

# 基于PRD精简版的科目分类映射字典
ACCOUNT_MAPPING = {
    # 流动资产分类
    'cash_equivalents': [
        '货币资金', '结算备付金', '拆出资金', '交易性金融资产', '衍生金融资产'
    ],
    'receivables': [
        '应收票据', '应收账款', '应收款项融资'
    ],
    'prepayments': [
        '预付款项'
    ],
    'inventory': [
        '存货'
    ],
    'other_current_assets': [
        '应收保费', '应收分保款项', '其他应收款', '买入返售金融资产',
        '合同资产', '持有待售资产', '一年内到期的非流动资产'
    ],

    # 非流动资产分类
    'long_term_investments': [
        '长期股权投资', '其他权益工具投资', '其他非流动金融资产'
    ],
    'fixed_assets': [
        '固定资产', '在建工程'
    ],
    'intangible_goodwill': [
        '无形资产', '商誉'
    ],
    'other_non_current_assets': [
        '发放贷款和垫资', '债权投资', '投资性房地产', '使用权资产',
        '开发支出', '长期待摊费用', '递延所得税资产'
    ],

    # 流动负债分类
    'short_term_debt': [
        '短期借款', '向中央银行借款', '拆入资金', '衍生金融负债',
        '一年内到期的非流动负债'
    ],
    'payables': [
        '应付票据', '应付账款', '其他应付款'
    ],
    'advance_receipts': [
        '预收款项', '合同负债'
    ],
    'accrued_expenses': [
        '应付职工薪酬', '应交税费'
    ],
    'other_current_liabilities': [
        '卖出回购金融资产款', '吸收存款及同行存放',
        '代理买卖证券款', '持有待售负债', '其他流动负债'
    ],

    # 非流动负债分类
    'long_term_debt': [
        '长期借款', '应付债券'
    ],
    'other_non_current_liabilities': [
        '保险合同准备金', '租赁负债', '长期应付款',
        '长期应付职工薪酬', '预计负债', '递延收益', '递延所得税负债'
    ],

    # 所有者权益分类
    'share_capital': [
        '实收资本', '股本'
    ],
    'capital_reserves': [
        '资本公积'
    ],
    'retained_earnings': [
        '盈余公积', '未分配利润'
    ],
    'other_equity': [
        '其他综合收益', '专项储备'
    ]
}

# 分类层次结构定义
CATEGORY_HIERARCHY = {
    'current_assets': [
        'cash_equivalents', 'receivables', 'prepayments', 
        'inventory', 'other_current_assets'
    ],
    'non_current_assets': [
        'long_term_investments', 'fixed_assets', 'intangible_goodwill', 
        'other_non_current_assets'
    ],
    'current_liabilities': [
        'short_term_debt', 'payables', 'advance_receipts', 
        'accrued_expenses', 'other_current_liabilities'
    ],
    'non_current_liabilities': [
        'long_term_debt', 'other_non_current_liabilities'
    ],
    'equity': [
        'share_capital', 'capital_reserves', 'retained_earnings', 'other_equity'
    ]
}

# 中文显示名称映射
CATEGORY_DISPLAY_NAMES = {
    # 流动资产
    'cash_equivalents': '现金类',
    'receivables': '应收款类',
    'prepayments': '预付款类',
    'inventory': '存货类',
    'other_current_assets': '其他流动类',
    
    # 非流动资产
    'long_term_investments': '长期投资类',
    'fixed_assets': '固定资产类',
    'intangible_goodwill': '无形资产&商誉类',
    'other_non_current_assets': '其他固定类',
    
    # 流动负债
    'short_term_debt': '短期借款类',
    'payables': '应付款类',
    'advance_receipts': '预收项类',
    'accrued_expenses': '薪酬&税类',
    'other_current_liabilities': '其他负债类',
    
    # 非流动负债
    'long_term_debt': '长期借款类',
    'other_non_current_liabilities': '其他非流动债类',
    
    # 所有者权益
    'share_capital': '股本类',
    'capital_reserves': '资本公积类',
    'retained_earnings': '留存收益类',
    'other_equity': '其他权益类',
    
    # 大类
    'current_assets': '流动资产',
    'non_current_assets': '非流动资产',
    'current_liabilities': '流动负债',
    'non_current_liabilities': '非流动负债',
    'equity': '所有者权益'
}


class AccountClassifier:
    """财务科目分类器"""
    
    def __init__(self):
        """初始化分类器"""
        self.mapping = ACCOUNT_MAPPING
        self.hierarchy = CATEGORY_HIERARCHY
        self.display_names = CATEGORY_DISPLAY_NAMES
        
        # 创建反向映射，用于快速查找
        self._create_reverse_mapping()
    
    def _create_reverse_mapping(self):
        """创建从科目名称到分类的反向映射"""
        self.reverse_mapping = {}
        
        for category, accounts in self.mapping.items():
            for account in accounts:
                self.reverse_mapping[account] = category
    
    def classify_account(self, account_name: str) -> str:
        """
        对单个科目进行分类
        
        Args:
            account_name: 科目名称
            
        Returns:
            分类标签，如果无法分类则返回'unknown'
        """
        if not account_name:
            return 'unknown'
        
        # 精确匹配
        if account_name in self.reverse_mapping:
            return self.reverse_mapping[account_name]
        
        # 模糊匹配
        for category, accounts in self.mapping.items():
            for account in accounts:
                if account in account_name or account_name in account:
                    return category
        
        logger.warning(f"无法分类的科目: {account_name}")
        return 'unknown'
    
    def classify_dataframe(self, df: pd.DataFrame, 
                          account_column: str = '科目') -> pd.DataFrame:
        """
        对DataFrame中的科目进行批量分类
        
        Args:
            df: 包含财务数据的DataFrame
            account_column: 科目列的名称
            
        Returns:
            添加了category列的DataFrame
        """
        if df.empty or account_column not in df.columns:
            logger.warning("DataFrame为空或缺少科目列")
            return df
        
        # 应用分类
        df = df.copy()
        df['category'] = df[account_column].apply(self.classify_account)
        
        # 统计分类结果
        category_counts = df['category'].value_counts()
        logger.info(f"科目分类完成，共分类 {len(df)} 条记录")
        logger.info(f"分类统计: {category_counts.to_dict()}")
        
        return df
    
    def get_category_hierarchy(self) -> Dict[str, List[str]]:
        """获取分类层次结构"""
        return self.hierarchy.copy()
    
    def get_display_name(self, category: str) -> str:
        """获取分类的中文显示名称"""
        return self.display_names.get(category, category)
    
    def get_main_category(self, sub_category: str) -> str:
        """获取子分类所属的主分类"""
        for main_cat, sub_cats in self.hierarchy.items():
            if sub_category in sub_cats:
                return main_cat
        return 'unknown'
    
    def aggregate_by_category(self, df: pd.DataFrame, 
                            amount_column: str = '金额',
                            date_column: str = '报告日期') -> pd.DataFrame:
        """
        按分类聚合财务数据
        
        Args:
            df: 包含分类信息的DataFrame
            amount_column: 金额列名称
            date_column: 日期列名称
            
        Returns:
            按分类聚合后的DataFrame
        """
        if df.empty:
            return df
        
        # 按日期和分类聚合
        aggregated = df.groupby([date_column, 'category'])[amount_column].sum().reset_index()
        
        # 添加显示名称
        aggregated['category_display'] = aggregated['category'].apply(self.get_display_name)
        
        # 添加主分类
        aggregated['main_category'] = aggregated['category'].apply(self.get_main_category)
        aggregated['main_category_display'] = aggregated['main_category'].apply(self.get_display_name)
        
        return aggregated


# 全局分类器实例
account_classifier = AccountClassifier()
